package com.frontalcode 
{
	import flash.display.*;
	import flash.events.*;
	
	/**
	 * The ContainerInput class handles the <input /> tag.
	 */
	public class ContainerInput extends Container
	{
		/**
		 * The Flash InteractiveObject supporting this input.
		 */
		public var input : InteractiveObject;
		private var _form : DocumentElement;
		
		/**
		 * Creates a new ContainerInput instance.
		 * 
		 * @param document	The document this element belongs to.
		 * @param parent	The element's parent in the document tree.
		 * @param node		The XML node this element is associated with.
		 * @param options	Options affecting the behavior of this instance.
		 * 					(This object does not have built-in support for any
		 * 					options.)
		 */
		public function ContainerInput ( document : Document, parent : DocumentElement, node : XML, options : Object = null )
		{
			super ( document, parent, node, options );
			
			processesOwnContent = true;
		}
		
		/**
		 * @private
		 */
		override public function applyMovieStyles ( ) : void
		{
			super.applyMovieStyles ( );
			
			if ( input != null )
			{
				var uiComponentClass : Class = document.externalAssetManager.getDefinition ( "fl.core.UIComponent" ) as Class;
				if ( form != null && form.focusMgr != null && input is uiComponentClass )
				{
					if ( ( input as uiComponentClass ).focusManager !== form.focusMgr && ( input as uiComponentClass ).focusManager != null )
					{
						// Flash adds a default FocusManager to the Stage for
						// new UIComponents. This FocusManager seems to conflict
						// with the FocusManagers we create with the form tags.
						// So if it looks like our input has this default
						// FocusManager, we grab it so we can deactivate it. 
						// (There doesn't seem to be any other way to get this
						// FocusManager.)
						//
						ContainerForm.stageFocusMgr = ( input as uiComponentClass ).focusManager;
					}
					( input as uiComponentClass ).focusManager = form.focusMgr;
				}
				
				if ( ! isNaN ( getAttribute ( "tabIndex" ) ) ) 
				{
					input.tabIndex = Number ( getAttribute ( "tabIndex" ) );
					if ( form != null && ( form.initialFocus == null || form.initialFocus.input.tabIndex > input.tabIndex ) ) form.initialFocus = this;
				}

				addListener ( input, FocusEvent.FOCUS_IN,  inputFocusHandler );
				addListener ( input, FocusEvent.FOCUS_OUT, inputFocusHandler );
			}
		}
		
		/**
		 * @private
		 */
		internal function inputFocusHandler ( event : FocusEvent ) : void
		{
			if ( event.type == FocusEvent.FOCUS_IN && form != null ) form.activate ( );
		}
		
		/**
		 * The value associated with this input.
		 */
		public function get value ( ) : * { return runInteractions ( "getValue" ); }
		
		/**
		 * The form associated with this input.
		 */
		public function get form ( ) : ContainerForm
		{
			if ( _form == null ) 
			{
				var scan : DocumentElement = parent;
				
				while ( scan != document && scan != null )
				{
					if ( scan is ContainerForm ) break;
					scan = scan.parent;
				}
				
				_form = scan;
			}
			
			return _form == document ? null : _form as ContainerForm;
		}
		
		/**
		 * @private
		 */
		override public function get intrinsicWidth ( ) : Number 
		{
			var value : Number;
			if ( input != null )
			{
				value = input.width;
				if ( isNaN ( value ) )
				{
					// For some reason UIComponent won't return the actual 
					// width of the input if you don't set it so we examine the
					// DisplayObject.
					//
					value = input.getRect ( input ).width;
				}
			}
			return value;
		}
		
		/**
		 * @private
		 */
		override public function get intrinsicHeight ( ) : Number 
		{ 
			var value : Number;
			if ( input != null )
			{
				value = input.height;
				if ( isNaN ( value ) )
				{
					// For some reason UIComponent won't return the actual 
					// height of the input if you don't set it so we examine the
					// DisplayObject.
					//
					value = input.getRect ( input ).height;
				}
			}
			return value;
		}
	}
}
